﻿#pragma once

#include "udp_defines.hh"
#include <ctime>
#include <list>
#include <memory>

namespace kratos {
namespace network {

// UDP套接字
class UdpSocket {
  // 读/写包
  struct Buffer {
    Buffer(const char *data, std::size_t size, const SocketAddress &address);
    char buffer_[NETWORK_IOLOOP_UDP_PACKET_MAX_SIZE]; // 缓冲区
    char *data_{nullptr};                                  // 可读/写地址
    std::size_t size_{0};                                  // 可读/写长度
    SocketAddress address_;                                // 地址
  };
  SocketType socket_; // 套接字
  using BufferList = std::list<Buffer *>;
  BufferList readBuffers_;  // 读缓冲区列表
  BufferList writeBuffers_; // 写缓冲区列表
  BufferList deadBuffers_;  // 需要销毁的缓冲区

public:
  // 构造
  // @param socket 套接字
  UdpSocket(SocketType socket);
  // 析构
  ~UdpSocket();
  // 调用底层事件机构
  // @param million 最长等待时间（毫秒）
  void update(std::time_t million);
  // 发送
  // @param buffer 数据指针
  // @param length 数据长度
  // @param address 目标地址
  void sendto(const char *buffer, std::size_t &length, const SocketAddress &address);
  // 接收
  // @param buffer 数据指针
  // @param length 数据长度
  // @param [IN OUT] address 来源地址
  bool recvfrom(char *buffer, std::size_t &length, SocketAddress &address);
  // 关闭
  void close();
  // 有效性判定
  operator bool();
};

} // namespace network
} // namespace kratos
